package com.gs.cd.utils.jwt;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;

/**
 * Created by hippo  2020/2/20
 *
 * @Description
 */
public class JwtUtils {
    public final static String USER_ID = "user_id";
    public final static String SSO_USER_ID = "sso_user_id";
    public final static String SSO_TICKET = "sso_ticket";
    public final static String EMAIL = "email";
    public final static String USER_NAME = "name"; //姓名
    private final static String DEFAULT_ENCRYPT_KEY = "DEK_1NiJ9.eyJm_2020_jMo_i9O";


    /**
     * 生成jwt签名
     *
     * @return
     */
    public static String sign(JwtUserInfo jwtUserInfo, String encryptJWTKey) {
        Algorithm algorithm = getAlgorithm(encryptJWTKey);
        // 附带account帐号信息
        return JWT.create()
                .withSubject(jwtUserInfo.getLoginName())
                .withClaim(USER_ID, jwtUserInfo.getUserId())
                .withClaim(SSO_USER_ID, jwtUserInfo.getSsoUserId())
                .withClaim(EMAIL, jwtUserInfo.getEmail())
                .withClaim(SSO_TICKET, jwtUserInfo.getSsoTicket())
                .withClaim(USER_NAME, jwtUserInfo.getUserName())
//                .withExpiresAt(DateUtils.addDays(DateUtils.getNowDate(), 7))//token有效时长 基于状态，{7天}，但不一定能验证通过
                .sign(algorithm);
    }

    public static String sign(JwtUserInfo jwtUserInfo) {
        return sign(jwtUserInfo, DEFAULT_ENCRYPT_KEY);
    }


    /**
     * 验证token
     *
     * @param token
     * @param encryptJWTKey
     * @return
     */
    public static boolean verify(String token, String encryptJWTKey) {
        return decodedJWT(token, encryptJWTKey) != null;
    }

    public static boolean verify(String token) {
        return verify(token, DEFAULT_ENCRYPT_KEY);
    }

    public static JwtUserInfo getJwtUserInfo(String token) {
        return getJwtUserInfo(token, DEFAULT_ENCRYPT_KEY);
    }

    public static JwtUserInfo getJwtUserInfo(String token, String encryptJWTKey) {
        JwtUserInfo jwtUserInfo = new JwtUserInfo();
        DecodedJWT jwt = decodedJWT(token, encryptJWTKey);
        if (jwt != null) {
            String loginName = jwt.getSubject();
            String userName = jwt.getClaim(USER_NAME).asString();
            Long userId = jwt.getClaim(USER_ID).asLong();
            String ssoUserId = jwt.getClaim(SSO_USER_ID).asString();
            String email = jwt.getClaim(EMAIL).asString();
            jwtUserInfo = new JwtUserInfo(loginName, userName, userId, ssoUserId, email);
        }

        return jwtUserInfo;
    }

    private static DecodedJWT decodedJWT(String token, String encryptJWTKey) {

        Algorithm algorithm = getAlgorithm(encryptJWTKey);

        JWTVerifier verifier = JWT.require(algorithm).build();
        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        } catch (Exception e) {
        }

        return jwt;
    }

    private static Algorithm getAlgorithm(String encryptJWTKey) {
        if (StrUtil.isEmpty(encryptJWTKey)) {
            encryptJWTKey = DEFAULT_ENCRYPT_KEY;
        }

        Algorithm algorithm = Algorithm.HMAC256(encryptJWTKey);
        return algorithm;
    }

}